package org.fastsyncer.manager.splitter;

import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;

import org.fastsyncer.common.constant.ConnectorConstant;
import org.fastsyncer.common.entity.MappingTask;
import org.fastsyncer.manager.splitter.impl.LdapSplitter;
import org.fastsyncer.manager.splitter.impl.MysqlSplitter;
import org.fastsyncer.manager.splitter.impl.OracleSplitter;
import org.fastsyncer.manager.splitter.impl.SqlMysqlSplitter;
import org.fastsyncer.manager.splitter.impl.SqlOracleSplitter;
import org.fastsyncer.manager.splitter.impl.SqlServerSplitter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class SplitterFactory {

	private static final Logger logger = LoggerFactory.getLogger(SplitterFactory.class);

	private static volatile SplitterFactory instance = null;

    private SplitterFactory(){
    }
    
    public static SplitterFactory getInstance() {
        if (null == instance) {
            synchronized (SplitterFactory.class) {
                if (null == instance) {
                    instance = new SplitterFactory();
                }
            }
        }
        return instance;
    }
    
    // 存放连接器实例
    private final static Map<String, Splitter> MAP = new ConcurrentHashMap<String, Splitter>();
    
    static {
        MAP.put(ConnectorConstant.MYSQL_CONNECTOR, MysqlSplitter.getInstance());
        MAP.put(ConnectorConstant.ORACLE_CONNECTOR, OracleSplitter.getInstance());
        MAP.put(ConnectorConstant.SQLSERVER_CONNECTOR, SqlServerSplitter.getInstance());
        MAP.put(ConnectorConstant.SQL_MYSQL_CONNECTOR, SqlMysqlSplitter.getInstance());
        MAP.put(ConnectorConstant.SQL_ORACLE_CONNECTOR, SqlOracleSplitter.getInstance());
        MAP.put(ConnectorConstant.LDAP_CONNECTOR, LdapSplitter.getInstance());
    }

	/**
	 * 计算总进度
	 * 
	 * @param mappingTask
	 * @return
	 */
	public void countProcess(MappingTask mappingTask) {
		// 总数据量
		int total = mappingTask.getSourceMapping().getRowCount();
		if(total < 1){
			return;
		}
		// 完成进度(必须大于等于0)
		int completed = mappingTask.getProcessCompleted();
		// 任务上线值,建议大于batchNum
		int maxTask = mappingTask.getMaxTask();
		// 总进度
		int process = total % maxTask == 0 ? total / maxTask : total / maxTask + 1;
		mappingTask.setProcess(process);
		logger.info("Total:" + total);
		logger.info("Progress:" + process);
		logger.info("Completed progress:" + completed);
	}

	/**
     * 拆分数据源为多个任务
     * @param mappingTask
     * @return 返回待执行的任务范围[100000000,100000999],[100001000,100001999],...
     */
	public Queue<Integer[]> split(MappingTask mappingTask) {
	    // 获取数据源连接器
		String connector = mappingTask.getSourceMapping().getConnector();
		Splitter splitter = MAP.get(connector);
		if(null == splitter){
		    return null;
		}
		return splitter.split(mappingTask);
	}

}
